package com.puzzlebazar.client.hashiwokakero;

import com.puzzlebazar.client.puzzle.model.Move;
import com.puzzlebazar.client.squaregrid.control.ControlView;
import com.puzzlebazar.client.squaregrid.control.HighlightControl;
import com.puzzlebazar.client.squaregrid.view.CellHighlighterBasic;
import com.puzzlebazar.client.squaregrid.view.ComponentHighlighter;
import com.puzzlebazar.client.squaregrid.view.GridDisplay;
import com.puzzlebazar.client.squaregrid.view.EdgeHighlighterBasic;
import com.puzzlebazar.client.squaregrid.view.HighlightConstraintsBasic;
import com.puzzlebazar.client.squaregrid.view.VertexHighlighterBasic;
import com.puzzlebazar.client.squaregrid.view.SGViewImpl;
import com.puzzlebazar.client.squaregrid.view.DrawableLayer;
import com.puzzlebazar.client.util.Observable;
import com.puzzlebazar.client.util.Vec2i;

public final class HashiwokakeroView extends SGViewImpl  {

	private final GridDisplay displayDecorator = new GridDisplay();
	private final DrawableLayer highlightLayer = new DrawableLayer();
	private final DrawableLayer bitmapLayer = new DrawableLayer();
	private final DrawableLayer stringLayer = new DrawableLayer();
	private final ControlView controlDecorator = new ControlView();	
	
	private final DrawMoveVisitor drawVisitor;
	
	
	/**
	 * Creates a new standard heyawake view
	 * 
	 * @param model  Heyawake model to view
	 * @param pixelSize Horizontal/Vertical size, in pixels
	 * @param bleed Amount of bleed around grid, in pixels
	 * @throws Exception
	 */
	public HashiwokakeroView( HashiwokakeroModel model, Vec2i pixelSize, int bleed ) throws Exception {
		super(model, pixelSize, bleed);
		
		add( displayDecorator );
		add( highlightLayer );
		add( bitmapLayer );
		add( stringLayer );
		add( controlDecorator );
		
		ComponentHighlighter highlighter = new ComponentHighlighter(
				new VertexHighlighterBasic(highlightLayer,"grayfill transparent", "H1"),
				new EdgeHighlighterBasic(highlightLayer,"grayfill transparent", "H2"),
				new CellHighlighterBasic(highlightLayer,"grayfill transparent", "H3") );

		new HighlightControl(
				new HighlightConstraintsBasic( true, true, true ),
				highlighter,
				controlDecorator );				
		
		drawVisitor = new DrawMoveVisitor( bitmapLayer, stringLayer );
		
		model.addObserver( this );
	}
	

	@Override
	public void update(Observable observable, Object arg) {
		assert observable instanceof HashiwokakeroModel;
		HashiwokakeroModel model = (HashiwokakeroModel)observable;
		try {
			Move move;

			if( arg != null ) {
				assert arg instanceof Move;
				move = (Move)arg;
			}
			else {
				bitmapLayer.clear();
				stringLayer.clear();

				move = model.getMoveList();
			}

			move.accept( drawVisitor );
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}	
	
}
